package com.company.cloud.club.modules.controller;

import cn.hutool.core.codec.Base64;
import com.company.cloud.club.modules.constants.CardFileTypeConstant;
import com.company.cloud.club.modules.constants.FileType;
import com.company.cloud.club.modules.constants.RecommendCardType;
import com.company.cloud.club.modules.core.dto.ListParam;
import com.company.cloud.club.modules.core.dto.Result;
import com.company.cloud.club.modules.core.util.DateUtil;
import com.company.cloud.club.modules.core.util.ValidateUtil;
import com.company.cloud.club.modules.db.dao.FileInfoMapper;
import com.company.cloud.club.modules.db.dao.ProductInfoMapper;
import com.company.cloud.club.modules.db.domain.*;
import com.company.cloud.club.modules.db.domain.Collection;
import com.company.cloud.club.modules.dto.IdQuery;
import com.company.cloud.club.modules.dto.LayTableResult;
import com.company.cloud.club.modules.dto.club.RecommendTypeDto;
import com.company.cloud.club.modules.dto.product.ProductBo;
import com.company.cloud.club.modules.dto.recommend.RecommendCardBo;
import com.company.cloud.club.modules.service.*;
import com.company.cloud.club.modules.utils.LoginContextUtils;
import com.company.cloud.club.modules.vo.ActivityVo;
import com.company.cloud.club.modules.vo.ClubMemberVo;
import com.company.cloud.club.modules.vo.ClubVo;
import com.company.cloud.club.modules.vo.RecommendCardVo;
import com.company.cloud.common.auth.annotation.StaffLogc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/recommend")
public class RecommendController {

    @Autowired
    private PraiseService praiseService;

    @Autowired
    private ClubInfoService clubInfoService;

    @Autowired
    private ClubActivityService clubActivityService;

    @Autowired
    private ClubMemberService clubMemberService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private RecommendService recommendService;

    @Autowired
    private CollectionService collectionService;

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Autowired
    private FriendDynamicService friendDynamicService;

    @Autowired
    private ProductInfoMapper productInfoMapper;

    /**
     * 动态列表
     *
     * @return
     */
    @GetMapping(value = "admin/list")
    public LayTableResult adminRecommendList(RecommendCard params) {
        Integer currentUserId = LoginContextUtils.getUserId();

        Integer currentPage = params.getCurrentPage();
        Integer pageSize = params.getPageSize();
        Integer begin = (currentPage - 1) * pageSize;

        List<RecommendCardVo> voList = new ArrayList<>();
        Integer isPublish = params.getIsPublish();
        List<RecommendCard> list = recommendService.selectAllDynamic(isPublish, begin, pageSize);
        int count = recommendService.countAllDynamic(isPublish);
        for (RecommendCard card : list) {
            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);

            String clubId = card.getClubId();
            ClubInfo clubInfo = clubInfoService.getById(clubId);
            if (ValidateUtil.isValid(clubInfo)) {
                vo.setClub(new ClubVo(clubInfo.getId(), clubInfo.getName(), clubInfo.getAvatar()));
            }

            String parentId = card.getParentId();
            ClubActivity activity = clubActivityService.getById(parentId);
            if (ValidateUtil.isValid(activity)) {
                vo.setActivity(new ActivityVo(activity.getTitle(), activity.getLabel(), activity.getBanner()));
            }

            UserInfo userInfo = userInfoService.getById(currentUserId);
            vo.setIsForbidden(userInfo.getForbiddenDt() != null &&
                    LocalDateTime.now().isBefore(userInfo.getForbiddenDt()));

            voList.add(vo);

        }

        return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, count);

    }

    /**
     * @return
     */
    @GetMapping(value = "list")
    public Result recommendList(@Valid @ModelAttribute RecommendTypeDto bo) {
        Integer currentUserId = LoginContextUtils.getUserId();

        List<RecommendCardVo> voList = new ArrayList<>();
        List<RecommendCard> list = recommendService.selectTopAll(bo.getType());
        for (RecommendCard card : list) {
            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);
            voList.add(vo);
        }

        return Result.ok(voList);

    }

    /**
     * 查询群公告
     *
     * @return
     */
    @GetMapping(value = "notice/list")
    public Result noticeList(@Valid @ModelAttribute IdQuery bo) {
        Integer currentUserId = LoginContextUtils.getUserIdOrNotLogin();

        List<RecommendCardVo> voList = new ArrayList<>();
        List<RecommendCard> list = recommendService.noticeList(bo.getId());
        for (RecommendCard card : list) {
            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);
            voList.add(vo);
        }

        return Result.ok(voList);

    }

    @GetMapping(value = "/admin/sub/list")
    public Result subRecommendList(@Valid @ModelAttribute ListParam bo) {
        Integer currentUserId = LoginContextUtils.getUserId();

        Integer currentPage = bo.getCurrentPage();
        Integer pageSize = bo.getPageSize();
        Integer begin = (currentPage - 1) * pageSize;

        List<RecommendCardVo> voList = new ArrayList<>();
        List<RecommendCard> list = recommendService.pageByParentId(bo.getId(), begin, pageSize);
        for (RecommendCard card : list) {

            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);

            String parentId = card.getParentId();
            RecommendCard parentCard = recommendService.getById(parentId);
            if (ValidateUtil.isValid(parentCard)) {
                RecommendCardVo parentCardVo = new RecommendCardVo();
                parentCardVo.setId(parentCard.getId());
                parentCardVo.setTitle(parentCard.getTitle());
                parentCardVo.setContent(parentCard.getContent());
                vo.setParentRecommendVo(parentCardVo);

                Integer parentUser = parentCard.getUserId();
                UserInfo userInfo = userInfoService.getById(parentUser);
                vo.setParentMemberVo(new ClubMemberVo(userInfo.getId(), userInfo.getNickName(), userInfo.getHeadImg(), "成员"));
            }

            voList.add(vo);

        }

        return Result.ok(voList);

    }

    /**
     * 我的关注
     *
     * @return
     */
    @GetMapping(value = "mine")
    public LayTableResult mineRecommendList(@Valid @ModelAttribute ListParam bo) {
        Integer currentUserId = LoginContextUtils.getUserId();

        Set<String> collList = new HashSet<>();

        for (ClubMember clubMember : clubMemberService.selectByUserId(currentUserId)) {
            collList.add(clubMember.getClubId());
        }

        for (Collection collection : collectionService.getCollectionList(currentUserId, "user")) {
            collList.add(collection.getResId());
        }

        List<RecommendCardVo> voList = new ArrayList<>();
        if (collList.isEmpty()) {
            return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, 0);
        }

        Integer currentPage = bo.getCurrentPage();
        Integer pageSize = bo.getPageSize();
        Integer begin = (currentPage - 1) * pageSize;

        List<RecommendCard> list = recommendService.selectMyFollow(collList, begin, pageSize);
        int count = recommendService.countMyFollow(collList);
        for (RecommendCard card : list) {

            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);
            voList.add(vo);

        }

        return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, count);

    }

    /**
     * 用户的动态
     *
     * @return
     */
    @GetMapping(value = "user/dynamic")
    public LayTableResult userDynamicRecommendList(@Valid @ModelAttribute ListParam bo) {
        Integer currentUserId = LoginContextUtils.getUserIdOrNotLogin();

        Integer uid = currentUserId;
        String userId = bo.getId();
        if (ValidateUtil.isValid(userId)) {
            uid = Integer.parseInt(userId);
            UserInfo userInfo = userInfoService.getById(uid);
            if (ValidateUtil.isEmpty(userInfo)) {
                uid = currentUserId;
            }
        }

        Integer currentPage = bo.getCurrentPage();
        Integer pageSize = bo.getPageSize();
        Integer begin = (currentPage - 1) * pageSize;

        List<RecommendCard> list = recommendService.pageByUserId(uid, begin, pageSize);
        int count = recommendService.countByUserId(uid);

        List<RecommendCardVo> voList = new ArrayList<>();
        for (RecommendCard card : list) {
            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);
            voList.add(vo);
        }

        return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, count);

    }

    /**
     * 好友动态
     *
     * @return
     */
    @GetMapping(value = "friend/dynamic")
    public LayTableResult friendDynamic(@Valid @ModelAttribute ListParam bo) {
        Integer currentUserId = LoginContextUtils.getUserId();

        Set<String> collList = new HashSet<>();
        for (Collection collection : collectionService.getCollectionList(currentUserId, "user")) {
            collList.add(collection.getResId());
        }

        List<RecommendCardVo> voList = new ArrayList<>();
        if (collList.isEmpty()) {
            return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, 0);
        }

        Integer currentPage = bo.getCurrentPage();
        Integer pageSize = bo.getPageSize();
        Integer begin = (currentPage - 1) * pageSize;

        List<FriendDynamic> list = friendDynamicService.selectMyFriend(collList, begin, pageSize);
        if (ValidateUtil.isEmpty(list)) {
            return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, 0);
        }

        int count = friendDynamicService.countMyFriend(collList);
        for (FriendDynamic card : list) {
            RecommendCardVo vo = new RecommendCardVo();
            vo.setTitle(card.getTitle());
            vo.setType(card.getType());
            vo.addImg(card.getImg());
            Integer userId = card.getUserId();
            UserInfo userInfo = userInfoService.getById(userId);
            vo.setUserId(userId);
            vo.setCtime(DateUtil.timeToStr(card.getTimeCreated(), DateUtil.DATE_MINI_PATTERN));
            if (ValidateUtil.isValid(userInfo)) {
                vo.setAvatar(userInfo.getHeadImg());
                vo.setNickname(userInfo.getNickName());
            } else {
                vo.setAvatar("https://img.artshanghaifair.com/assets/img/acCircle/Head-portrait.png");
                vo.setNickname("艺术家");
            }
            voList.add(vo);
        }

        return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, count);

    }

    /**
     * 添加动态或评论
     *
     * @param bo
     * @return
     */
    @PostMapping(value = "add")
    @StaffLogc(title = "动态添加", action = "动态添加", actionAdo = "动态列表")
    public Result add(@Valid @RequestBody RecommendCardBo bo) {
        Integer currentUserId = LoginContextUtils.getUserId();

        UserInfo userInfo = userInfoService.getById(currentUserId);
        if (userInfo.getForbiddenDt() != null &&
                LocalDateTime.now().isBefore(userInfo.getForbiddenDt())) {
            throw new RuntimeException("您已被禁言，请联系管理员");
        }
        if(ValidateUtil.isValid(bo.getLabel())){
            userInfo.setLabel(bo.getLabel());
            userInfo.setId(userInfo.getId());
            userInfoService.updateById(userInfo);
        }

        RecommendCard card = new RecommendCard(0);
        card.setTitle(bo.getTitle());
        String type = bo.getType();
        card.setType(ValidateUtil.isEmpty(type) ? "评论" : type);
        card.setUserId(currentUserId);
        card.setContent(bo.getContent());
        card.setParentId(bo.getParentId());
        card.setFileType(bo.getFileType());
        card.setPraiseNum(0);
        card.setIsPublish(2);
        card.setProductNo(bo.getProductNo());
        String clubId = bo.getClubId();
        card.setClubId(ValidateUtil.isEmpty(clubId) ? "0" : clubId);

        if ("评论".equals(card.getType())) {
            if (ValidateUtil.isEmpty(card.getParentId()) || "0".equals(card.getParentId())) {
                throw new RuntimeException("评论的ParentId不能为空");
            } else {
                card.setFileType(CardFileTypeConstant.TEXT);

                FriendDynamic fd = new FriendDynamic(0);
                fd.setUserId(currentUserId);
                fd.setDynamicUserId(currentUserId);
                fd.setTitle(card.getContent());
                fd.setType("评论");
                friendDynamicService.save(fd);

            }
        }

        if (CardFileTypeConstant.VIDEO.equals(card.getFileType())) {
            card.setIsPublish(0);
            if (bo.getImgUrls().size() > 1) {
                throw new RuntimeException("视频条数不能超过1");
            }
        }

        boolean flag = recommendService.save(card);

        if (!flag) {
            throw new RuntimeException("评论保存失败");
        }

        for (String imgUrl : bo.getImgUrls()) {
            FileInfo fileInfo = new FileInfo();
            fileInfo.setResId(card.getId());
            fileInfo.setResUrl(imgUrl);
            fileInfo.setUserId(currentUserId);
            if (CardFileTypeConstant.VIDEO.equals(card.getFileType())) {
                fileInfo.setType(FileType.VIDEO);
            } else {
                fileInfo.setType(FileType.IMAGE);
            }
            fileInfoMapper.insert(fileInfo);
        }

        return Result.ok(card.getId());
    }

    /**
     * 删除动态
     *
     * @param bo
     * @return
     */
    @StaffLogc(title = "动态删除", action = "动态删除", actionAdo = "动态列表")
    @PostMapping(value = "remove")
    public Result remove(@Valid @RequestBody IdQuery bo) {
        Integer currentUserId = LoginContextUtils.getUserId();
        boolean flag = recommendService.removeRecom(bo.getId());
        return Result.ok(flag);
    }

    /**
     * 审核通过
     *
     * @param bo
     * @return
     */

    @PostMapping(value = "publish")
    @StaffLogc(title = "审核通过", action = "动态审核", actionAdo = "社区动态")
    public Result publish(@Valid @RequestBody IdQuery bo) {
        Integer currentUserId = LoginContextUtils.getUserId();
        boolean flag = recommendService.publishRecom(bo.getId());

        if (flag) {
            RecommendCard card = recommendService.getById(bo.getId());
            FriendDynamic fd = new FriendDynamic(0);
            fd.setUserId(currentUserId);
            fd.setDynamicUserId(currentUserId);
            fd.setTitle(card.getContent());
            fd.setType(card.getType());
            friendDynamicService.save(fd);
        }

        return Result.ok(flag);
    }

    /**
     * 推荐|取消推荐
     *
     * @param bo
     * @return
     */
    @PostMapping(value = "suggest")
    public Result suggest(@Valid @RequestBody IdQuery bo) {
        LoginContextUtils.getUserId();
        int flag = recommendService.suggestRecom(bo.getId());
        return Result.ok(flag == 0 ? "取消推荐" : "推荐成功");
    }

    /**
     * 推荐|取消精华
     *
     * @param bo
     * @return
     */
    @PostMapping(value = "update/essence")
    @StaffLogc(title = "推荐|取消精华", action = "推荐|取消精华", actionAdo = "圈精华")
    public Result essence(@Valid @RequestBody IdQuery bo) {
        LoginContextUtils.getUserId();
        int flag = recommendService.updateEssenceRecom(bo.getId());
        return Result.ok(flag == 0 ? "取消圈精华" : "设置成功");
    }

    /**
     * 主题|手记详情
     *
     * @param bo
     * @return
     */
    @GetMapping(value = "detail")
    public Result detail(@Valid @ModelAttribute IdQuery bo) {
        Integer currentUserId = LoginContextUtils.getUserIdOrNotLogin();

        RecommendCard card = recommendService.getById(bo.getId());
        if (ValidateUtil.isEmpty(card)) {
            throw new RuntimeException("数据不存在");
        }

        RecommendCardVo vo = new RecommendCardVo();
        vo.setCollectionNum(collectionService.countNum("artDetail", card.getId()));
        initRecommendCardVo(vo, card, currentUserId);

        vo.setType(card.getType());
        vo.setIsColled(collectionService.isColled(card.getId(), currentUserId));
        vo.setIsColledAuthor(collectionService.isColled(String.valueOf(card.getUserId()), currentUserId));

        /**
         * 相关交流圈
         */
        String clubId = card.getClubId();
        ClubInfo clubInfo = clubInfoService.getById(clubId);
        if (ValidateUtil.isValid(clubInfo)) {
            ClubVo clubVo = new ClubVo(clubInfo.getId(), clubInfo.getName(), clubInfo.getAvatar());
            List<ClubMember> memberList = clubMemberService.selectByClubId(clubId);
            for (ClubMember member : memberList) {
                Integer userId = member.getUserId();
                UserInfo memberUser = userInfoService.getById(userId);
                if (ValidateUtil.isValid(memberUser)) {
                    clubVo.addMember(new ClubMemberVo(userId, memberUser.getNickName(), memberUser.getHeadImg(), member.getType()));
                }
            }
            clubVo.setNum(memberList.size());
            vo.setClub(clubVo);
        }


        List<RecommendCard> list = recommendService.queryByParentId(bo.getId());
        for (RecommendCard subCard : list) {

            if (subCard.getIsPublish() != 2) {
                continue;
            }

            RecommendCardVo subVo = new RecommendCardVo();
            initRecommendCardVo(subVo, subCard, currentUserId);

            List<RecommendCard> thirdList = recommendService.queryByParentId(subCard.getId());
            for (RecommendCard thirdCard : thirdList) {
                RecommendCardVo thirdVo = new RecommendCardVo();
                initRecommendCardVo(thirdVo, thirdCard, currentUserId);
                subVo.addChildren(thirdVo);
            }

            vo.addChildren(subVo);

        }

        if (CardFileTypeConstant.VIDEO.equals(card.getFileType())) {
            List<RecommendCard> suggestList = recommendService.selectByFileTypeAndSuggest(CardFileTypeConstant.VIDEO, 1);
            for (RecommendCard videoCard : suggestList) {
                RecommendCardVo videoVo = new RecommendCardVo();
                initRecommendCardVo(videoVo, videoCard, currentUserId);
                vo.addRelative(videoVo);
            }
        }

        return Result.ok(vo);

    }

    /**
     * 相关推荐
     *
     * @return
     */
    @GetMapping(value = "relative/sug")
    public LayTableResult relativeSug(@Valid @ModelAttribute ListParam bo) {
        Integer currentUserId = LoginContextUtils.getUserIdOrNotLogin();

        Integer currentPage = bo.getCurrentPage();
        Integer pageSize = bo.getPageSize();
        Integer begin = (currentPage - 1) * pageSize;

        List<RecommendCardVo> voList = new ArrayList<>();
        String cardId = bo.getId();
        RecommendCard recommendCard = recommendService.getById(cardId);
        String clubId = recommendCard.getClubId();

        List<RecommendCard> list = recommendService.selectByClubId(clubId, begin, pageSize);
        int count = recommendService.countByClubId(clubId);
        for (RecommendCard card : list) {

            if (cardId.equals(card.getId())) {
                continue;
            }

            if (card.getIsPublish() != 2) {
                continue;
            }

            RecommendCardVo vo = new RecommendCardVo();
            initRecommendCardVo(vo, card, currentUserId);
            voList.add(vo);

        }

        return new LayTableResult(Result.SUCCESS_CODE, "获取成功", voList, count);

    }

    private void initRecommendCardVo(RecommendCardVo vo, RecommendCard card, Integer currentUserId) {

        vo.setId(card.getId());
        vo.setTitle(card.getTitle());
        vo.setContent(card.getContent());
        vo.setCommentNum(recommendService.countComment(card.getId()));
        vo.setPraiseNum(card.getPraiseNum());
        vo.setIsAuthor(currentUserId.equals(card.getUserId()));
        vo.setIsColled(collectionService.isColled(card.getId(), currentUserId));
        vo.setIsColledAuthor(collectionService.isColled(String.valueOf(card.getUserId()), currentUserId));
        vo.setCollectionNum(collectionService.countNum("artDetail", card.getId()));
        vo.setIsPraise(praiseService.isPraise(card.getId(), currentUserId));
        vo.setIsEssence(card.getIsEssence() == 1);
        vo.setCtime(DateUtil.timeToStr(card.getTimeCreated(), DateUtil.DATE_MINI_PATTERN));
        vo.setType(card.getType());
        vo.setFileType(card.getFileType());
        vo.setIsSug(card.getIsSuggest() == 1);

        String productNo = card.getProductNo();
        ProductInfo productInfo = productInfoMapper.findByProductNo(productNo);
        if (ValidateUtil.isValid(productInfo)) {
            ProductBo productBo = new ProductBo();
            productBo.setProductNo(productNo);
            productBo.setName(productInfo.getName());
            productBo.setImg(productInfo.getImage());
            productBo.setPrice(productInfo.getPrice());
            vo.setProduct(productBo);
        }

        Integer subUserId = card.getUserId();
        UserInfo userInfo = userInfoService.getById(subUserId);
        if (ValidateUtil.isValid(userInfo)) {
            vo.setNickname(userInfo.getNickName());
            vo.setAvatar(userInfo.getHeadImg());
            vo.setLabel("");
            if(ValidateUtil.isValid(userInfo.getLabel())){
                vo.setLabel(userInfo.getLabel());
            }
            vo.setUserId(subUserId);
        }

        List<FileInfo> subImgUrlIds = fileInfoMapper.selectByResId(card.getId());
        for (FileInfo fileInfo : subImgUrlIds) {
            vo.addImg(fileInfo.getResUrl());
        }

        ClubActivity activity = clubActivityService.getById(card.getParentId());
        if (ValidateUtil.isValid(activity)) {
            ActivityVo activityVo = new ActivityVo(activity.getTitle(), activity.getLabel(), activity.getBanner(), activity.getJoinNum());
            activityVo.setId(activity.getId());
            vo.setActivity(activityVo);
        }

    }

}
